﻿namespace DataIntegration.Storage.SQL
{
    using System.Collections.Generic;
    using System.Reflection;
    using System.Text;
    using log4net;

    public abstract class SQLDataStoreFactory : IDataStoreFactory
    {
        private static readonly ILog Logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().ReflectedType);

        private readonly IList<TableDesign> tableDesigns;

        protected SQLDataStoreFactory(string connectionString, IList<TableDesign> tableDesigns)
        {
            this.ConnectionString = connectionString;
            this.tableDesigns = tableDesigns;
        }

        protected string ConnectionString { get; private set; }

        public abstract bool TableExists(string name);

        public abstract void DeleteTable(string name);

        public abstract void RunCommand(string commandText);

        public abstract IDataStore BuildDataStore();

        public IDataStore GetDataStore()
        {
            Logger.Debug("Getting DataStore");

            foreach (TableDesign tableDesign in TableDesigns)
            {
                if (this.TableExists(tableDesign.Name))
                {
                    this.DeleteTable(tableDesign.Name);
                }

                StringBuilder createTableStatement = new StringBuilder();
                createTableStatement.AppendFormat("CREATE TABLE {0} (", tableDesign.Name);

                foreach (KeyValuePair<string, string> keyValuePair in tableDesign.Columns)
                {
                    string columnName = keyValuePair.Key;
                    string sqlType = keyValuePair.Value;
                    createTableStatement.AppendFormat("{0} {1},", columnName, sqlType);
                }

                createTableStatement.Remove(createTableStatement.Length - 1, 1);
                createTableStatement.Append(")");

                this.RunCommand(createTableStatement.ToString());
            }

            return this.BuildDataStore();
        }

        public IList<TableDesign> TableDesigns
        {
            get { return this.tableDesigns; }
        }

        public IDictionary<string, string> GetColumns(string name)
        {
            foreach (TableDesign tableDesign in TableDesigns)
            {
                if (tableDesign.Name == name)
                {
                    return tableDesign.Columns;
                }
            }

            return new Dictionary<string, string>();
        }
    }
}
